package org.dxy.domain.handler.productionLine;

import com.google.common.eventbus.EventBus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.domain.exception.DomainException;
import org.dxy.domain.handler.CommandHandler;
import org.dxy.domain.port.repository.IProcessRouteRepository;
import org.dxy.domain.port.repository.IProductionLineRepository;
import org.dxy.domain.command.productionLine.ReconfigureProductionLineCommand;
import org.dxy.domain.model.aggregate.ProductionLine;
import org.dxy.types.common.CommandResult;
import org.springframework.stereotype.Component;

/**
 * @description: 产线配置更新命令处理器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ReconfigureProductionLineCommandHandler implements CommandHandler<ReconfigureProductionLineCommand, Void> {

    private final IProductionLineRepository productionLineRepository;
    private final IProcessRouteRepository processRouteRepository;
    private final EventBus eventBus;

    @Override
    public CommandResult<Void> handle(ReconfigureProductionLineCommand command) {
        // 1. 从仓储加载产线聚合
        ProductionLine line = productionLineRepository.findById(command.getLineId());
        if (line == null) {
            log.error("未找到产线，command={}", command);
            return CommandResult.fail("产线不存在");
        }

        // 2. 验证配置参数
        validateConfigurationParameters(command);

        // 3. 调用聚合根重新配置方法（内部会添加事件到事件列表）
        line.reconfigure(command);

        // 4. 持久化变更
        productionLineRepository.save(line);

        // 5. 发布聚合产生的所有事件
        line.getDomainEvents().forEach(eventBus::post);

        // 6. 清理事件，防止重复发布
        line.clearDomainEvents();

        log.info("产线重新配置成功, command={}", command);
        return CommandResult.success( "产线重新配置成功");
    }

    private void validateConfigurationParameters(ReconfigureProductionLineCommand command) {
        // 验证工艺路径
        if (command.getNewProcessRouteId() != null) {
            processRouteRepository.findById(command.getNewProcessRouteId())
                    .orElseThrow(() -> new DomainException(null,command.getNewProcessRouteId().toString()));
        }

//        // 验证日产能目标
//        if (command.getNewDailyCapacityTarget() != null && command.getNewDailyCapacityTarget() <= 0) {
//            throw new IllegalArgumentException("日产能目标必须大于0");
//        }
    }
} 